iT邦幫忙

2021 iThome 鐵人賽

DAY 22
1
Mobile Development

認真學 Compose - 對 Jetpack Compose 的問題與探索系列 第 22

D22/ 怎麼在 Compose 中用 Material Theme? - Theme

  • 分享至 

  • xImage
  •  

今天大概會聊到的範圍

  • Theme

透過 Android Studio 內建的精靈建立一個新的 Compose 專案或是建立新的 "Empty Compose Activity" 時,會發現這樣的 code :


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ProjectNameTheme {  // <--- 今天主角
                // A surface container using the 'background' color from the theme
                Surface(color = MaterialTheme.colors.background) {
                    Greeting("Android")
                }
            }
        }
    }
}

可以發現預設的 Code 會在內容的 Composable 之外,再包一個 Theme。仔細研究一下這個 Theme。這個 Theme 通常是開啟新的 Compose 專案時自動建立的。可以觀察到這個 Theme 其實是對 MaterialTheme 的包裝。

@Composable
fun ProjectNameTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),    
    content: @Composable () -> Unit
) {
    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }
    
    MaterialTheme(
        colors = colors,
        typography = Typography,
        shapes = Shapes,
        content = content
    )
}

在 MaterialTheme 中,要提供 color 、typography、shapes。

設定的地方

    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }

在 Android Studio 自動建立的 Theme 中,會判斷是否是 dark mode,在不同的情況下使用不同的 "ColorPalette"

Color Palette 是 Material Design 中重要的概念。透過一組事先配好的顏色讓整個 App 的顏色有一致性。要提供 MaterialTheme color,我們要提供的 Colors 物件時就需要提供這個 Palette 中所需要的各個顏色:

class Colors(
    primary: Color,
    primaryVariant: Color,
    secondary: Color,
    secondaryVariant: Color,
    background: Color,
    surface: Color,
    error: Color,
    onPrimary: Color,
    onSecondary: Color,
    onBackground: Color,
    onSurface: Color,
    onError: Color,
    isLight: Boolean    // 是否是 dark mode 
)

除了顏色之外,typography 可以定義 h1 ~ body 等不同字級。可以參考 Material Design 的 Type System 、另外還有 Shape System 可以設定在不同的情況下物件的形狀。

使用的地方

Theme 已經配置好了,我們也將 content 包在 Theme 裡面了,那要怎麼取得我們 Theme 的配置呢?

@Composable
fun UIComposable() {
    MaterialTheme() {
        Card(modifier = Modifier.background(MaterialTheme.colors.background)) {
            // ...
        }
    }
}

我們只需要透過 MaterialTheme.(colors | typography | shapes) 就可以取得對應的參數了!


在 Compose 中,使用 Theme 真的非常的簡單,設定的地方和使用的地方都非常直覺。很好奇 Compose framework 實際上怎麼做到這件事的? 也許可以當成後續的主題吧!


Reference:


上一篇
D21/ 怎麼結合 ViewModel 和 Compose? - ViewModel
下一篇
D23/ MaterialTheme 怎麼運作的? - CompositionLocal
系列文
認真學 Compose - 對 Jetpack Compose 的問題與探索30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言